package test.dao;/*
 * Copyright (c) 2008-2012
 * LANIT
 * All rights reserved.
 *
 * This product and related documentation are protected by copyright and
 * distributed under licenses restricting its use, copying, distribution, and
 * decompilation. No part of this product or related documentation may be
 * reproduced in any form by any means without prior written authorization of
 * LANIT and its licensors, if any.
 *
 * $Id$
 */

import test.DataSourceFactory;
import test.NotUpdatedException;
import test.model.Order;

import javax.sql.DataSource;
import java.sql.*;

public class OrderDaoImpl implements OrderDao {

    private static final String SQL_SELECT_MAX_ID = "SELECT MAX(ID) FROM Record";
    private static final String SQL_INSERT_ROW = "INSERT INTO Record (ID ,Name, Description) VALUES (record_sq_id.nextval, ?, ?)";
    private static final String SQL_SELECT_BY_ID = "SELECT * FROM Record WHERE ID = ?";
    private static final String SQL_UPDATE_BY_ID = "UPDATE Record SET Name = ?, Description = ? WHERE ID = ?";
    private static final String SQL_DELETE_BY_ID = "DELETE FROM Record WHERE ID = ?";

    private DataSource dataSource;

    public OrderDaoImpl() throws SQLException {
        this.dataSource = new DataSourceFactory().getDataSource();
    }

    public Long add(Order order) {
        Connection connection = null;
        Statement statement = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        long id;
        int countRowUpdated;
        String methodName = "ADD";
        id = 0;

        try {
            connection = dataSource.getConnection();
            statement = connection.createStatement();
            preparedStatement = connection.prepareStatement(SQL_INSERT_ROW);

            preparedStatement.setString(1, order.getName());
            preparedStatement.setString(2, order.getDescription());

            countRowUpdated = preparedStatement.executeUpdate();

            if (countRowUpdated == 0) {
                throw new NotUpdatedException(methodName + ": Err");
            }

            //get last ID
            resultSet = statement.executeQuery(SQL_SELECT_MAX_ID);

            if (resultSet.next()) {
                id = resultSet.getInt(1);
                //                System.out.println("id = " + id);
            }
            return id;
        } catch (SQLException e) {
            throw new RuntimeException(e.getMessage(), e);
        } finally {
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if (preparedStatement != null) {
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (statement != null) {
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if (resultSet != null) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void update(Long id, String newName, String newDescription) {
        Connection connection = null;

        PreparedStatement preparedStatement = null;

        int countRowUpdated;
        String methodName;

        methodName = "UPDATE";

        try {
            connection = dataSource.getConnection();
            preparedStatement = connection.prepareStatement(SQL_UPDATE_BY_ID);

            preparedStatement.setLong(3, id);
            preparedStatement.setString(1, newName);
            preparedStatement.setString(2, newDescription);

            countRowUpdated = preparedStatement.executeUpdate();

            if (countRowUpdated == 0) {
                throw new NotUpdatedException(methodName + ": Record " + id + " is not found.");
            }

            //            System.out.println("UPDATE: countRowUpdated = " + countRowUpdated);
        } catch (SQLException e) {
            throw new RuntimeException(e.getMessage(), e);
        } finally {
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if (preparedStatement != null) {
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public void remove(Long id) {
        Connection connection = null;

        PreparedStatement preparedStatement = null;

        int countRowUpdated;
        String methodName;

        methodName = "REMOVE";
        try {
            connection = dataSource.getConnection();
            preparedStatement = connection.prepareStatement(SQL_DELETE_BY_ID);
            preparedStatement.setLong(1, id);

            countRowUpdated = preparedStatement.executeUpdate();

            if (countRowUpdated == 0) {
                throw new NotUpdatedException(methodName + ": Record " + id + " is not found.");
            }

            //            System.out.println("REMOVE: countRowUpdated = " + countRowUpdated);
        } catch (SQLException e) {
            throw new RuntimeException(e.getMessage(), e);
        } finally {
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if (preparedStatement != null) {
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public Order getById(Long id) {
        Connection connection = null;

        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        Order order;
        order = new Order();

        try {
            connection = dataSource.getConnection();

            preparedStatement = connection.prepareStatement(SQL_SELECT_BY_ID);
            preparedStatement.setLong(1, id);

            resultSet = preparedStatement.executeQuery();

            if (resultSet.next()) {
                order.setId(resultSet.getLong(1));
                order.setName(resultSet.getString(2));
                order.setDescription(resultSet.getString(3));
            } else {
                order = null;
            }

            return order;
        } catch (SQLException e) {
            throw new RuntimeException(e.getMessage(), e);
        } finally {
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if (preparedStatement != null) {
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if (resultSet != null) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
